#ifndef _PLUGINMANAGER_H_
#define _PLUGINMANAGER_H_

#include <dlfcn.h>
#include <string>
#include <map>
#include <vector>

#include "sensors/Sensor.h"
#include "sensors/Actuator.h"

typedef std::pair<std::string, std::string> ClassDescription ;

class PluginManager {
private :
	typedef std::vector<PluginDef> (*pluginsFunction)();
	typedef Sensor* (*create_sensor_function)(RobotMap*, Robot*) ;
	typedef Actuator* (*create_actuator_function)(RobotMap*, Robot*) ;
	typedef void (*destroy_sensor_function)(Sensor*);
	typedef void (*destroy_actuator_function)(Actuator*);
	
	destroy_sensor_function _destroySensor ;
	destroy_actuator_function _destroyActuator ;

	std::map<ClassDescription, void*> _sensors ;
	std::map<ClassDescription, void*> _actuators ;
	std::vector<void*> _libraries ;
	Robot* _robot ;
	RobotMap* _map ;
	
	static PluginManager* _pm ;
	
	PluginManager() ;
	PluginManager(const PluginManager& pm) ;
	PluginManager& operator=(const PluginManager& pm) ;
	
	void* sensorLibrary(const std::string& sensorClassName) const ;
	void* actuatorLibrary(const std::string& actuatorClassName) const ;
public :
	virtual ~PluginManager() ;
	static PluginManager& getInstance() ;
	static void killInstance() ;
	
	void setRobotMap(RobotMap* robotMap) ;
	void setRobot(Robot* robot) ;
	
	void loadLibrary(std::string fileName) ;
	
	std::vector<ClassDescription> sensors() const ;
	std::vector<ClassDescription> actuators() const ;
	
	Sensor* createSensor(const std::string& sensorClassName) const ;
	Actuator* createActuator(const std::string& actuatorClassName) const ;
	
	void destroySensor(Sensor* sensor) const ;
	void destroyActuator(Actuator* actuator) const ;
};

#endif // _PLUGINMANAGER_H_
